import fs from 'fs'
import * as sinon from 'sinon'
import {expect} from 'chai'
import * as download from '../../src/tool/download'
import {formatToLatestPatchVersion} from '../../src/tool/version'
describe('formatToLatestPatchVersion', () => {
    let stubDownload: sinon.SinonStub
    let stubRmSync: sinon.SinonStub
    let stubReadFileSync: sinon.SinonStub
    const downloadUrl ='http://the.flow.tool.registry.com/sometool/version.txt'
    beforeEach(() => {
        process.env['FLOW_TOOL_REGISTRY_URL'] = 'http://the.flow.tool.registry.com'
        stubDownload = sinon.stub(download, 'download')
        stubRmSync = sinon.stub(fs, 'rmSync')
        stubReadFileSync = sinon.stub(fs, 'readFileSync')
    })
    afterEach(() => {
        sinon.restore()
    })
    it('should get latest patch node version when input version is x', async() => {
        stubDownload.resolves('/some/downloaded/file')
        stubReadFileSync.withArgs('/some/downloaded/file', 'utf8').returns("v20.0.3/\nv20.0.2/\nv20.0.1/\nv20.0.0/\nv20.0.8/\nv20.0.9/\nv20.0.10/\nv20.0.11/\nv20.0.12/\nv20.1.3/\nv20.10.3/\nv20.12.3/\nv20.12.2/\nv20.2.3/\n")
        const result = await formatToLatestPatchVersion('node', "v",'20')
        expect(result).to.equals('v20.12.3')
    })
    it('should get latest patch node version when input version is x.y', async() => {
        stubDownload.resolves('/some/downloaded/file')
        stubReadFileSync.withArgs('/some/downloaded/file', 'utf8').returns("v20.0.3/\nv20.0.2/\nv20.0.1/\nv20.0.0/\nv20.0.8/\nv20.0.9/\nv20.0.10/\nv20.0.11/\nv20.0.12/\nv20.1.3/\nv20.10.3/\nv20.12.3/\nv20.12.2/\nv20.2.3/\n")
        const result = await formatToLatestPatchVersion('node', "v",'20.12')
        expect(result).equals('v20.12.3')
    })
    it('should get latest patch node version when input version is x.y', async() => {
        stubDownload.resolves('/some/downloaded/file')
        stubReadFileSync.withArgs('/some/downloaded/file', 'utf8').returns("v20.0.3/\nv20.0.2/\nv20.0.1/\nv20.0.0/\nv20.0.8/\nv20.0.9/\nv20.0.10/\nv20.0.11/\nv20.0.12/\nv20.1.3/\nv20.10.3/\nv20.12.3/\nv20.12.2/\nv20.2.3/\n")
        const result = await formatToLatestPatchVersion('node', "v",'20.0')
        expect(result).equals('v20.0.12')
    })
    it('should get latest patch node version when input version is x.y.z', async() => {
        stubDownload.resolves('/some/downloaded/file')
        stubReadFileSync.withArgs('/some/downloaded/file', 'utf8').returns("v20.0.3/\nv20.0.2/\nv20.0.1/\nv20.0.0/\nv20.0.8/\nv20.0.9/\nv20.0.10/\nv20.0.11/\nv20.0.12/\nv20.1.3/\nv20.10.3/\nv20.12.3/\nv20.12.2/\nv20.2.3/\n")
        const result = await formatToLatestPatchVersion('node', "v",'20.12.2')
        expect(result).equals('v20.12.2')
    })
    it('should get latest patch go version when input version is x', async() => {
        stubDownload.resolves('/some/downloaded/file')
        stubReadFileSync.withArgs('/some/downloaded/file', 'utf8').returns("1.21.5\n1.21.2\n1.21.1\n1.21.0\n1.21.3\n1.21.4\n1.21.9\n1.21.8\n1.21.7\n1.22.3\n1.22.0\n1.22.2\n1.22.1\n")
        const result = await formatToLatestPatchVersion('go', "",'1')
        expect(result).equals('1.22.3')
    })
    it('should get latest patch go version when input version is x.y', async() => {
        stubDownload.resolves('/some/downloaded/file')
        stubReadFileSync.withArgs('/some/downloaded/file', 'utf8').returns("1.21.5\n1.21.2\n1.21.1\n1.21.0\n1.21.3\n1.21.4\n1.21.9\n1.21.8\n1.21.7\n1.22.3\n1.22.0\n1.22.2\n1.22.1\n")
        const result = await formatToLatestPatchVersion('go', "",'1.21')
        expect(result).equals('1.21.9')
    })
    it('should get latest patch go version when input version is x.y.z', async() => {
        stubDownload.resolves('/some/downloaded/file')
        stubReadFileSync.withArgs('/some/downloaded/file', 'utf8').returns("1.21.5\n1.21.2\n1.21.1\n1.21.0\n1.21.3\n1.21.4\n1.21.9\n1.21.8\n1.21.7\n1.22.3\n1.22.0\n1.22.2\n1.22.1\n")
        const result = await formatToLatestPatchVersion('go', "",'1.22.3')
        expect(result).equals('1.22.3')
    })

    it('should throw new Error when input version not exist', async () => {
        stubDownload.resolves('/some/downloaded/file')
        stubReadFileSync.withArgs('/some/downloaded/file', 'utf8').returns("1.21.5\n1.21.2\n1.21.1\n1.21.0\n1.21.3\n1.21.4\n1.21.9\n1.21.8\n1.21.7\n1.22.3\n1.22.0\n1.22.2\n1.22.1\n")
        let result = "";
        try {
            result = await formatToLatestPatchVersion('go', "", '1.88')
            expect(true).to.equals(false)
        } catch (e) {
            expect(result).to.equals("")
        }
    })

    it('should throw new Error when version.txt not exist', async () => {
        stubDownload.rejects('version.txt not exist')
        let result = "";
        try {
            result = await formatToLatestPatchVersion('tool_not_exist', "", '1.21')
            expect(true).to.equals(false)
        } catch (e) {
            // @ts-ignore
            expect(e.message).to.equals("Get tool tool_not_exist-1.21 from http://the.flow.tool.registry.com/tool_not_exist/versions.txt error: version.txt not exist.")
        }
    })

    it('should return directly when input version is x.y.z', async() => {
        stubDownload.resolves('/some/downloaded/file')
        stubReadFileSync.withArgs('/some/downloaded/file', 'utf8').returns("")
        const result = await formatToLatestPatchVersion('go', "",'1.100.100')
        expect(result).equals('1.100.100')

        const result2 = await formatToLatestPatchVersion('node', "v",'1.200.200')
        expect(result2).equals('v1.200.200')
    })
})
